//////////////////////////////////////
// Fast Container Library           //
// MIT License - Copyright (c) 2012 //
//////////////////////////////////////

#pragma once

#include "type_traits.h"

FC_NAMESPACE_BEGIN


struct doubly_linked_node
{
	doubly_linked_node* prev;
	doubly_linked_node* next;

	static void link( doubly_linked_node* a, doubly_linked_node* b )
	{
		a->prev = b->prev;
		a->next = b;
		a->prev->next = b->prev = a;
	}

	static void unlink( doubly_linked_node* n )
	{
		n->prev->next = n->next;
		n->next->prev = n->prev;
	}

	static void reverse( node* pivot )
	{
		node* p = pivot;
		do {
			fc::swap( p->next, p->prev );
			p = p->prev;
		}
		while( p != pivot );
	}

	static void splice( doubly_linked_node* n, doubly_linked_node* first, doubly_linked_node* last )
	{
		n->prev->next = first;
		first->prev->next = last;
		last->prev->next  = n;

		doubly_linked_node* p = n->prev;
		n->prev = last->prev;
		last->prev = first->prev;
		first->prev = p;
	}

	static void swap( list_node_base& a, list_node_base& b )
	{
		fc::swap( a, b );

		//if a node is self-linked (empty), then we have to re-link to self.
		if( a.next == a.prev ) a.next = a.prev = (T*)&a;
		if( b.next == b.prev ) b.next = b.prev = (T*)&b;
		a.prev->next = a.next->prev = (T*)&a;
		b.prev->next = b.next->prev = (T*)&b;
	}
};


template <class T> struct is_pod< single_linked_node<T> > : integral_constant <bool, is_pod<T>::value> { };
template <class T> struct is_pod< node<T> > : integral_constant <bool, is_pod<T>::value> { };
template <class T> struct has_trivial_constructor< node<T> > : integral_constant <bool, has_trivial_constructor<T>::value> { };
template <class T> struct has_trivial_copy< node<T> > : integral_constant <bool, has_trivial_copy<T>::value> { };
template <class T> struct has_trivial_assign< node<T> > : integral_constant <bool, has_trivial_assign<T>::value> { };


FC_NAMESPACE_END
